home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / rspfcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  9.8 KB  |  401 lines

  1. #include "global.h"
  2. #include "mbuf.h"
  3. #include "proc.h"
  4. #include "timer.h"
  5. #include "iface.h"
  6. #include "cmdparse.h"
  7. #include "netuser.h"
  8. #include "rspf.h"
  9. #include "commands.h"
  10.  
  11. int Rspfownmode = -1;
  12. static int dointerface __ARGS((int argc,char *argv[],void *p));
  13. static int domessage __ARGS((int argc,char *argv[],void *p));
  14. static int domaxping __ARGS((int argc,char *argv[],void *p));
  15. static int domode __ARGS((int argc,char *argv[],void *p));
  16. static int dorrhtimer __ARGS((int argc,char *argv[],void *p));
  17. static int dotimer __ARGS((int argc,char *argv[],void *p));
  18. static int doroutes __ARGS((int argc,char *argv[],void *p));
  19. static int dostatus __ARGS((int argc,char *argv[],void *p));
  20. static int dosuspect __ARGS((int argc,char *argv[],void *p));
  21. static struct timer rrhtimer, rspftimer;
  22.  
  23. static struct cmds Rspfcmds[] = {
  24.     "interface",    dointerface,    0,    0,    NULLCHAR,
  25.     "message",    domessage,    0,    0,    NULLCHAR,
  26.     "maxping",    domaxping,    0,    0,    NULLCHAR,
  27.     "mode",        domode,        0,    0,    NULLCHAR,
  28.     "rrhtimer",    dorrhtimer,    0,    0,    NULLCHAR,
  29.     "routes",    doroutes,    0,    0,    NULLCHAR,
  30.     "status",    dostatus,    0,    0,    NULLCHAR,
  31.     "suspecttimer",    dosuspect,    0,    0,    NULLCHAR,
  32.     "timer",    dotimer,    0,    0,    NULLCHAR,
  33.     NULLCHAR
  34. };
  35.  
  36. int
  37. dorspf(argc,argv,p)
  38. int argc;
  39. char *argv[];
  40. void *p;
  41. {
  42.     return subcmd(Rspfcmds,argc,argv,p);
  43. }
  44.  
  45. /* The suspect timer controls how often old links expire. When a link has
  46.  * expired, we try to renew its entry by various methods.
  47.  */
  48. static int
  49. dosuspect(argc,argv,p)
  50. int argc;
  51. char *argv[];
  52. void *p;
  53. {
  54.     if(Rspfifaces == NULLRIFACE){
  55.         tprintf("RSPF is not active - define interface first.\n");
  56.         return 0;
  57.     }
  58.     if(argc < 2){
  59.         tprintf("Suspect timer: %lu/%lu seconds\n",
  60.         read_timer(&Susptimer) * MSPTICK/1000,
  61.         dur_timer(&Susptimer) * MSPTICK/1000);
  62.         return 0;
  63.     }
  64.     Susptimer.func = rspfsuspect; /* what to call on timeout */
  65.     Susptimer.arg = NULL;            /* dummy value */
  66.     set_timer(&Susptimer,atol(argv[1])*1000); /* set timer duration */
  67.     start_timer(&Susptimer);        /* and fire it up */
  68.     return 0;
  69. }
  70.  
  71. /* The RRH timer controls the interval between Router-To-Router Hello
  72.  * messages. These messages announce that your station is live and well
  73.  * and that you are willing to exchange RSPF routing updates.
  74.  */
  75. static int
  76. dorrhtimer(argc,argv,p)
  77. int argc;
  78. char *argv[];
  79. void *p;
  80. {
  81.     if(Rspfifaces == NULLRIFACE){
  82.         tprintf("RSPF is not active - define interface first.\n");
  83.         return 0;
  84.     }
  85.     if(argc < 2){
  86.         tprintf("RRH timer: %lu/%lu seconds\n",
  87.         read_timer(&rrhtimer) * MSPTICK/1000,
  88.         dur_timer(&rrhtimer) * MSPTICK/1000);
  89.         return 0;
  90.     }
  91.     rrhtimer.func = rspfevent; /* what to call on timeout */
  92.     rrhtimer.arg = (void *) &rrhtimer;
  93.     set_timer(&rrhtimer,atol(argv[1])*1000); /* set timer duration */
  94.     start_timer(&rrhtimer);        /* and fire it up */
  95.     return 0;
  96. }
  97.  
  98. /* This timer controls the interval between the RSPF routing updates. */
  99. static int
  100. dotimer(argc,argv,p)
  101. int argc;
  102. char *argv[];
  103. void *p;
  104. {
  105.     if(Rspfifaces == NULLRIFACE){
  106.         tprintf("RSPF is not active - define interface first.\n");
  107.         return 0;
  108.     }
  109.     if(argc < 2){
  110.         tprintf("RSPF update timer: %lu/%lu seconds\n",
  111.         read_timer(&rspftimer) * MSPTICK/1000,
  112.         dur_timer(&rspftimer) * MSPTICK/1000);
  113.         return 0;
  114.     }
  115.     rspftimer.func = rspfevent; /* what to call on timeout */
  116.     rspftimer.arg = (void *) &rspftimer;
  117.     set_timer(&rspftimer,atol(argv[1])*1000); /* set timer duration */
  118.     start_timer(&rspftimer);        /* and fire it up */
  119.     return 0;
  120. }
  121.  
  122. /* Called when either the RRH timer, the Update timer or the Suspect timer
  123.  * expires.
  124.  */
  125. void
  126. rspfevent(t)
  127. void *t;
  128. {
  129.      int cmd;
  130.      struct mbuf *bp;
  131.      struct rspfadj *adj = NULLADJ;
  132.      struct timer *tp;
  133.      tp = (struct timer *) t;
  134.      if(tp == &rrhtimer) {
  135.       cmd = RSPFE_RRH;
  136.       start_timer(tp);
  137.      }
  138.      else if(tp == &rspftimer) {
  139.       cmd = RSPFE_UPDATE;
  140.       start_timer(tp);
  141.      }
  142.      else {
  143.       for(adj = Adjs; adj != NULLADJ; adj = adj->next)
  144.            if(&adj->timer == tp)
  145.             break;
  146.       if(adj == NULLADJ)
  147.            return;
  148.       cmd = RSPFE_CHECK;
  149.      }
  150.      bp = ambufw(1+sizeof(int32));
  151.      *bp->data = cmd;
  152.      memcpy(bp->data + 1,&adj,sizeof(adj));
  153.      bp->cnt = bp->size;
  154.      enqueue(&Rspfinq,bp);
  155. }
  156.  
  157. static int
  158. domessage(argc,argv,p)
  159. int argc;
  160. char *argv[];
  161. void *p;
  162. {
  163.     if(argc > 2) {
  164.         tprintf("Usage: rspf message \"<your message>\"\n");
  165.         return 0;
  166.     }
  167.  
  168.     if(argc < 2) {
  169.         if(Rrh_message != NULLCHAR)
  170.             tprintf(Rrh_message);
  171.     }
  172.     else {
  173.         if(Rrh_message != NULLCHAR){
  174.             free(Rrh_message);
  175.             Rrh_message = NULLCHAR;    /* reset the pointer */
  176.         }
  177.         if(!strlen(argv[1]))
  178.             return 0;        /* clearing the buffer */
  179.         Rrh_message = mallocw(strlen(argv[1])+5);/* allow for EOL */
  180.         strcpy(Rrh_message, argv[1]);
  181.         strcat(Rrh_message, INET_EOL);    /* add the EOL char */
  182.     }
  183.     return 0;
  184. }
  185.  
  186. static int
  187. domaxping(argc,argv,p)
  188. int argc;
  189. char *argv[];
  190. void *p;
  191. {
  192.      return setshort(&Rspfpingmax,"Max failed pings before deleting adjacency",
  193.              argc,argv);
  194. }
  195.  
  196. static int
  197. domode(argc,argv,p)
  198. int argc;
  199. char *argv[];
  200. void *p;
  201. {
  202.     if(argc < 2) {
  203.     tprintf("RSPF preferred mode is ");
  204.     if(Rspfownmode == -1)
  205.         tprintf("not set.\n");
  206.     else
  207.         tprintf("%s.\n",(Rspfownmode & CONNECT_MODE) ? "VC mode" :
  208.            "Datagram mode");
  209.     return 0;
  210.     }
  211.     switch(*argv[1]){
  212.     case 'v':
  213.     case 'c':
  214.     case 'V':
  215.     case 'C':
  216.     Rspfownmode = CONNECT_MODE;
  217.     break;
  218.     case 'd':
  219.     case 'D':
  220.     Rspfownmode = DATAGRAM_MODE;
  221.     break;
  222.     case 'n':
  223.     case 'N':
  224.     Rspfownmode = -1;
  225.     break;
  226.     default:
  227.     tprintf("Usage: rspf mode [vc | datagram | none]\n");
  228.     return 1;
  229.     }
  230.     return 0;
  231. }
  232.  
  233. static int
  234. dointerface(argc,argv,p)
  235. int argc;
  236. char *argv[];
  237. void *p;
  238. {
  239.     struct rspfiface *riface;
  240.     struct iface *iface;
  241.     struct mbuf *bp;
  242.     int h,q;
  243.     if(argc < 2){
  244.     tprintf("Iface    Quality    Horizon\n");
  245.     for(riface = Rspfifaces; riface != NULLRIFACE; riface = riface->next)
  246.         tprintf("%-9s%-11d%-11d\n",riface->iface->name,riface->quality,
  247.            riface->horizon);
  248.     return 0;
  249.     }
  250.     if(argc != 4){
  251.     tprintf("Usage: rspf interface <name> <quality> <horizon>\n");
  252.     return 1;
  253.     }
  254.     if((iface = if_lookup(argv[1])) == NULLIF){
  255.     tprintf("No such interface.\n");
  256.     return 1;
  257.     }
  258.     if(iface->broadcast == 0){
  259.     tprintf("Broadcast address for interface %s not set\n",argv[1]);
  260.     return 1;
  261.     }
  262.     q = atoi(argv[2]);
  263.     if(q < 1 || q > 127){
  264.     tprintf("Quality must be between 1 and 127\n");
  265.     return 1;
  266.     }
  267.     h = atoi(argv[3]);
  268.     if(h < 1 || h > 255){
  269.     tprintf("Horizon must be between 1 and 255\n");
  270.     return 1;
  271.     }
  272.     riface = (struct rspfiface *)callocw(1,sizeof(struct rspfiface));
  273.     riface->iface = iface;
  274.     riface->quality = q;
  275.     riface->horizon = h;
  276.     riface->next = Rspfifaces;
  277.     if(Rspfifaces == NULLRIFACE)
  278.      newproc("RSPF",2048,rspfmain,0,NULL,NULL);
  279.     Rspfifaces = riface;
  280.     bp = ambufw(1+sizeof(int32));
  281.     *bp->data = RSPFE_RRH;        /* Send an RRH immediately */
  282.     memcpy(bp->data + 1,&riface,sizeof(riface));
  283.     bp->cnt = bp->size;
  284.     enqueue(&Rspfinq,bp);
  285.     return 0;
  286. }
  287.  
  288. /* Display accumulated routing updates */
  289. static int
  290. doroutes(argc,argv,p)
  291. int argc;
  292. char *argv[];
  293. void *p;
  294. {
  295.     struct mbuf *bp;
  296.     struct rspfrouter *rr;
  297.     if(Rspfifaces == NULLRIFACE){
  298.     tprintf("RSPF is not active - define interface first.\n");
  299.     return 0;
  300.     }
  301.     bp = makeownupdate(INADDR_ANY,0);
  302.     if(bp == NULLBUF && Rspfrouters == NULLRROUTER) {
  303.      tprintf("No routing information is available.\n");
  304.      return 0;
  305.     }
  306.     if(bp != NULLBUF) {
  307.     tprintf("      Local routing update:\n");
  308.     rspfnodedump(NULLFILE,&bp,0);
  309.     tprintf("\n");
  310.     }
  311.     for(rr = Rspfrouters; rr != NULLRROUTER; rr = rr->next) {
  312.     tprintf("      Time since receipt: %s",tformat(Clock - rr->time));
  313.     if(rr->subseq != 0)
  314.          tprintf("  Last subseq: %u",uchar(rr->subseq));
  315.     if(rr->sent)
  316.          tprintf("  Propagated");
  317.     tprintf("\n");
  318.     if(rr->data != NULLBUF) {
  319.          dup_p(&bp,rr->data,0,len_p(rr->data));
  320.          rspfnodedump(NULLFILE,&bp,0);
  321.          tprintf("\n");
  322.     }
  323.     }
  324.     return 0;
  325. }
  326.  
  327. static int
  328. dostatus(argc,argv,p)
  329. int argc;
  330. char *argv[];
  331. void *p;
  332. {
  333.     struct rspfreasm *re;
  334.     struct rspfadj *adj;
  335.     struct mbuf *bp;
  336.     union rspf rspf;
  337.     if(Rspfifaces == NULLRIFACE){
  338.         tprintf("RSPF is not active - define interface first.\n");
  339.         return 0;
  340.     }
  341.     tprintf("Bad checksum %u  Bad version %u  Not RSPF interface %u\n",
  342.         Rspf_stat.badcsum,Rspf_stat.badvers,Rspf_stat.norspfiface);
  343.     tprintf("RRH in %u  RRH out %u  Update in %u  Update out %u\n",
  344.         Rspf_stat.rrhin,Rspf_stat.rrhout,Rspf_stat.updatein,
  345.         Rspf_stat.updateout);
  346.     tprintf("Non-adjacency update %u  Old node report %u  Polls sent %u\n",
  347.         Rspf_stat.noadjupdate,Rspf_stat.oldreport,Rspf_stat.outpolls);
  348.     if(Adjs == NULLADJ)
  349.         return 0;
  350.     tprintf("Addr            Cost    Seq    Heard    Timer     TOS    State\n");
  351.     for(adj = Adjs; adj != NULLADJ; adj = adj->next) {
  352.         tprintf("%-15s %4u  %5u   %6lu ", inet_ntoa(adj->addr),
  353.             uchar(adj->cost),adj->seq,adj->heard);
  354.         if(run_timer(&adj->timer))
  355.              tprintf("%5lu/%-5lu",read_timer(&adj->timer) * MSPTICK
  356.                  / 1000,dur_timer(&adj->timer) * MSPTICK/1000);
  357.         else
  358.              tprintf("%11s","");
  359.         tprintf("  %3u    ", uchar(adj->tos));
  360.         switch(adj->state) {
  361.         case RSPF_TENTATIVE:
  362.             tprintf("Tentative");
  363.             break;
  364.         case RSPF_OK:
  365.             tprintf("OK");
  366.             break;
  367.         case RSPF_SUSPECT:
  368.             tprintf("Suspect");
  369.             break;
  370.         case RSPF_BAD:
  371.             tprintf("Bad");
  372.             break;
  373.         default:
  374.             tprintf("Unknown");
  375.             break;
  376.         }
  377.         tprintf("\n");
  378.     }
  379.     if(run_timer(&Rspfreasmt)) {
  380.          tprintf("Reassembly timer running: %lu/%lu seconds\n",
  381.              read_timer(&Rspfreasmt) * MSPTICK/1000,
  382.              dur_timer(&Rspfreasmt) * MSPTICK/1000);
  383.     }
  384.     if(Rspfreasmq != NULLRREASM)
  385.          tprintf("Reassembly fragments:\n");
  386.     for(re = Rspfreasmq; re != NULLRREASM; re = re->next) {
  387.          tprintf("src %s time since last frag %s",inet_ntoa(re->addr),
  388.              tformat(Clock - re->time));
  389.          if(dup_p(&bp,re->data,0,RSPFPKTLEN) == RSPFPKTLEN &&
  390.         ntohrspf(&rspf,&bp) != -1)
  391.           tprintf(" frag count %u/%u\n",len_q(re->data),
  392.               rspf.pkthdr.fragtot);
  393.          else {
  394.           tprintf("\n");
  395.           free_p(bp);
  396.           continue;
  397.          }
  398.     }
  399.     return 0;
  400. }
  401.